import { getCookie } from '@tencent/gh-qqnews-sdk/gh-qqnews-utils';
import { tips } from './client';

// tslint:disable-next-line
const noop = function () {};

let jpcount = 0;
export function jsonp(url: string) {
  return new Promise<any[]>((resolve) => {
    const script = document.createElement('script');
    script.charset = 'UTF-8';
    const name = `JP${jpcount}${Math.floor((new Date()).getTime() / 100)}`;
    jpcount += 1;
    // @ts-ignore
    window[name] = (...args: any[]) => {
      resolve(args);
      // @ts-ignore
      delete window[name];
      document.body.removeChild(script);
    };
    const T_URL = new URL(url);
    if (T_URL.search) T_URL.search += '&';
    T_URL.search += `callback=${name}`;
    script.src = T_URL.href;
    document.body.appendChild(script);
  });
}

export const loadjs = (url: string, fn = noop): void => {
  const script = document.createElement('script');
  script.type = 'text/javascript';
  script.async = true;
  script.onload = () => {
    fn?.();
  };
  script.src = url;

  const node = document.getElementsByTagName('script')[0];
  (node.parentNode as HTMLElement).insertBefore(script, node);
};

export const format = (template: string, ...args: any[]): string => {
  if (!template) {
    throw new Error('template params is required!');
  }

  const regExp = /([{}])\1|[{](.*?)(?:!(.+?))?[}]/g;

  let count = 0;
  while (regExp.exec(template)) {
    count = count + 1;
  }

  if (args.length < count) {
    if (count > 1) {
      throw new Error(`${count} arguments required, but only ${args.length} present at ${template}`);
    } else {
      throw new Error(`${count} argument required, but only ${args.length} present at ${template}`);
    }
  }

  let i = 0;
  const ret = template.replace(/([{}])\1|[{](.*?)(?:!(.+?))?[}]/g, () => {
    const match = args[i];
    i = i + 1;

    return match;
  });

  return ret;
};

function isEmpty(str: string) {
  if (str === undefined || str === '' || str === null) {
    return true;
  }
  return false;
}
function trim(str: string) {
  if (isEmpty(str)) {
    return str;
  }

  return str.replace(/(^\s*)|(\s*$)/g, '');
}

function charLength(str: string) {
  const nstr = str.replace(/[^x00-xff]/g, 'JJ');

  return nstr.length;
}

export const truncate = (str: any, size: any, tail: any) => {
  let nstr = trim(str);
  const cLen = charLength(nstr);
  const length = size <= 0 ? cLen : size;
  if (length >= cLen) return nstr;
  while (charLength(nstr) > length) {
    nstr = nstr.substr(0, nstr.length - 1);
  }
  nstr += tail || '...';

  return nstr;
};

export const getQQByUin = () => {
  const uin = getCookie('uin');

  if (uin) {
    let str = uin.substr(1);
    if (str.substr(1) === '0') {
      str = str.substr(1);
    }

    return str;
  }
  return '';
};

export const searchParams = (name: string) => {
  const url = window.location.href;
  const key = name.replace(/[[\]]/g, '\\$&');

  const regex = new RegExp(`[?&]${key}(=([^&#]*)|&|#|$)`);
  const ret = regex.exec(url);
  if (!ret) {
    return null;
  }

  if (!ret[2]) {
    return '';
  }

  return window.decodeURIComponent(ret[2].replace(/\+/g, ' '));
};

export const getRandomIntInclusive = (small: any, big: any) => {
  const min = Math.ceil(small);
  const max = Math.floor(big);
  return Math.floor(Math.random() * (max - min + 1)) + min;
};

export function warn(msg: string) {
  console.error(`[Signin App]: ${msg}`);
}

const padLeftZero = (str: string) => `00${str}`.substr(str.length);
export const showNetError = (code: number | string) => {
  console.log(code);
  tips('网络繁忙，请稍后再试');
};

// filters begin
export const formatDate = (date: any, fmt: string) => {
  let fmt1 = '';
  if (/(y+)/.test(fmt)) {
    fmt1 = fmt.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length));
  }
  const o: Record<string, any> = {
    'M+': date.getMonth() + 1,
    'd+': date.getDate(),
    'h+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds(),
  };
  Object.keys(o).forEach((k: string) => {
    if (new RegExp(`(${k})`).test(fmt1)) {
      const str = `${o[k]}`;
      fmt1 = fmt1.replace(RegExp.$1, RegExp.$1.length === 1 ? str : padLeftZero(str));
    }
  });
  return fmt1;
};

export const formatTimer = (time: any) => {
  let timestamp = time / 1;
  if (time.toString().length === 10) {
    timestamp = timestamp * 1000;
  }
  const date = new Date(timestamp);
  return formatDate(date, 'yyyy.MM.dd');
};

export const formatTimerMD = (time: any) => {
  let timestamp = time / 1;
  if (time.toString().length === 10) {
    timestamp = timestamp * 1000;
  }
  const date = new Date(timestamp);
  return formatDate(date, 'MM.dd');
};

export const formatDateStr = (dateStr: any, format: any) => {
  const date = new Date(dateStr);
  return formatDate(date, format);
};

export const formatFullDate = (time: any) => {
  let timestamp = time / 1;
  if (time.toString().length === 10) {
    timestamp = timestamp * 1000;
  }
  const date = new Date(timestamp);
  return formatDate(date, 'yyyy-MM-dd hh:mm:ss');
};

export const formatFullDateNew = (time: any) => {
  let timestamp = time / 1;
  if (time.toString().length === 10) {
    timestamp = timestamp * 1000;
  }
  const date = new Date(timestamp);
  return formatDate(date, 'yyyy-MM-dd hh:mm');
};

export const formatDay = (time: any) => {
  let timestamp = time / 1;
  if (time.toString().length === 10) {
    timestamp = timestamp * 1000;
  }
  const date = new Date(timestamp);
  return formatDate(date, 'dd');
};

export const formatHour = (time: any) => {
  let timestamp = time / 1;
  if (time.toString().length === 10) {
    timestamp = timestamp * 1000;
  }
  const date = new Date(timestamp);
  return formatDate(date, 'hh');
};

export const formatMinutes = (time: any) => {
  let timestamp = time / 1;
  if (time.toString().length === 10) {
    timestamp = timestamp * 1000;
  }
  const date = new Date(timestamp);
  return formatDate(date, 'mm');
};

export const formatSecond = (time: any) => {
  let timestamp = time / 1;
  if (time.toString().length === 10) {
    timestamp = timestamp * 1000;
  }
  const date = new Date(timestamp);
  return formatDate(date, 'ss');
};

// 判断时间戳是否当天
export const isToday = (time: any) => {
  const atime = formatDay(time);
  const btime = formatDay(Date.now());
  if (atime === btime) {
    return true;
  }
  return false;
};

// 保留两位小数的方法 红包金额是分
export const changeTwoDecimal = (x: string | number) => {
  // console.log('changeTwoDecimal')
  let fx = parseFloat(String(x)) / 100;
  if (isNaN(fx)) {
    // console.log('function:changeTwoDecimal->parameter error');
    return x;
  }
  fx = Math.round(Number(x) * 100) / 10000;
  let sx = fx.toString();
  let posdecimal = sx.indexOf('.');
  if (posdecimal < 0) {
    posdecimal = sx.length;
    sx += '.';
  }
  while (sx.length <= posdecimal + 2) {
    sx += '0';
  }
  return sx;
};
export const formatNumber = (n: string | number) => {
  const nstr = n.toString();
  return nstr[1] ? nstr : `0${nstr}`;
};
export const diffTime = (startDate: Date, endDate: Date) => {
  const diff = endDate.getTime() - startDate.getTime(); // 时间差的毫秒数
  // 计算出相差天数
  const days = Math.floor(diff / (24 * 3600 * 1000));
  // 计算出小时数
  const leave1 = diff % (24 * 3600 * 1000); // 计算天数后剩余的毫秒数
  const hours = formatNumber(String(Math.floor(leave1 / (3600 * 1000))));
  // 计算相差分钟数
  const leave2 = leave1 % (3600 * 1000); // 计算小时数后剩余的毫秒数
  const minutes = formatNumber(String(Math.floor(leave2 / (60 * 1000))));
  // 计算相差秒数
  const leave3 = leave2 % (60 * 1000); // 计算分钟数后剩余的毫秒数
  const seconds = formatNumber(String(Math.round(leave3 / 1000)));
  const tmpObj = {
    days,
    hours,
    minutes,
    seconds,
  };
  return tmpObj;
};

export const formatCount = (count: any) => {
  let countString = '';
  if (Number(count) >= 10000) {
    countString = `${(Number(count) / 10000).toFixed(1).toString()}万`;
  }
  return countString;
};
// filters end

// 获取元素距离页面顶部距离
export const getElementToPageTop = (el: any) => {
  if (el.parentElement) {
    const offsetTop: any = getElementToPageTop(el.parentElement) + el.offsetTop;
    return offsetTop;
  }
  return el.offsetTop;
};

/**
 * 检测图片是否存在
 * @param url
 */
export const imageIsExist = function (url: string) {
  return new Promise((resolve) => {
    let img: HTMLImageElement | null = new Image();
    img.onload = function () {
      resolve(true);
      img = null;
    };
    img.onerror = function () {
      resolve(false);
      img = null;
    };
    img.src = url;
  });
};

// 将分钟转换为年月日-时分
export const formatMsgTime = (dateTimeStamp: number) => {
  let result = '';
  const minute = 1000 * 60;
  const hour = minute * 60;
  const day = hour * 24;
  const month = day * 30;
  const now = new Date().getTime();
  const diffValue = now - dateTimeStamp;
  if (diffValue < 0) return;
  const monthC = diffValue / month;
  const weekC = diffValue / (7 * day);
  const dayC = diffValue / day;
  const hourC = diffValue / hour;
  const minC = diffValue / minute;
  if (monthC >= 1) {
    result = `${monthC}月前`;
  } else if (weekC >= 1) {
    result = `${weekC}周前`;
  } else if (dayC >= 1) {
    result = `${dayC}天前`;
  } else if (hourC >= 1) {
    result = `${hourC}小时前`;
  } else if (minC >= 1) {
    result = `${minC}分钟前`;
  } else {
    result = '刚刚';
  }
  return result;
};
// 根据设计图获取当前尺寸
export const getCurScreenWidth = (num: number, orgWidth: number) => {
  const width = document.body.clientWidth;
  const curNum = (width / orgWidth) * num;
  return curNum;
};
// 数字每3位加逗号
export const formatThousands = (number: number) => {
  if (!number) {
    return '';
  }
  const str = number.toString();
  const reg = str.indexOf('.') > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(?:\d{3})+$)/g;
  return str.replace(reg, '$1,');
};
// 手动计算vw尺寸
// 参数定义
// {w:需要计算的尺寸,ww:设计图整体宽度,}
export const getVw = (obj: { w: number; ww: number }) => {
  return `${(Number(obj.w) / Number(obj.ww)) * 100}vw`;
  return '';
};
export default {
  jsonp,
  loadjs,
  format,
  truncate,
  warn,
  searchParams,
  showNetError,
  formatTimer,
  formatTimerMD,
  formatDateStr,
  formatDay,
  formatHour,
  formatMinutes,
  formatSecond,
  formatFullDate,
  changeTwoDecimal,
  diffTime,
  formatNumber,
  formatCount,
  padLeftZero,
  isToday,
  formatFullDateNew,
  getElementToPageTop,
  imageIsExist,
  formatMsgTime,
  getCurScreenWidth,
};
